package com.kaige.asktaoplugin60.handler;

import com.kaige.asktaoplugin60.config.GameConfig;
import com.kaige.asktaoplugin60.config.PluginConfig;
import com.kaige.asktaoplugin60.enums.FunctionHeaderEnum;
import com.kaige.asktaoplugin60.utils.DataSender;
import com.kaige.asktaoplugin60.utils.HexUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

/**
 * 插件客户端处理器 - 处理来自游戏服务端的消息
 */
@Slf4j
public class PluginClientHandler extends ChannelInboundHandlerAdapter {

    // 连接到客户端的通道
    private Channel clientChannel;

    // 插件配置
    private PluginConfig pluginConfig;

    private GameConfig gameConfig;

    public PluginClientHandler(Channel clientChannel) {
        this.clientChannel = clientChannel;
    }

    public void setPluginConfig(PluginConfig pluginConfig) {
        this.pluginConfig = pluginConfig;
    }

    public void setGameConfig(GameConfig gameConfig) {
        this.gameConfig = gameConfig;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 接收到服务端消息
        ByteBuf buf = (ByteBuf) msg;
        // 输出十六进制格式的数据
        String hexData = HexUtil.byteBufToHex(buf);
        // 拷贝一份buf，用于后续的处理
        ByteBuf copy = buf.copy();
        // 获取功能头：data中的第11和12个字节
        byte[] functionHead = new byte[2];
        functionHead[0] = copy.getByte(10);
        functionHead[1] = copy.getByte(11);
        String functionHeader = HexUtil.bytesToHex(functionHead);
        // 使用枚举替代硬编码字符串
        FunctionHeaderEnum headerEnum = FunctionHeaderEnum.getByFunctionHeader(functionHeader);
        if (headerEnum != null) {
            switch (headerEnum) {
                case LOGIN_PANEL:
                    copy = dealLoginPanel(copy);
                    break;
                case LOGIN_LINE:
                    copy = dealLoginLine(copy);
                    break;
                case CHOSEN_LINE:
                    copy = dealChoseLine(copy);
                    break;
                case CHANGE_LINE:
                    copy = dealChangeLine(copy);
                    break;
                default:
                    break;
            }
        }

        DataSender.sendDataToClient(clientChannel, copy);

        buf.release();
    }

    private ByteBuf dealLoginPanel(ByteBuf copy) {
        ByteBuf buf4355 = Unpooled.buffer();
        copy.readBytes(10);
        buf4355.writeShort(copy.readShort());
        short lineNumbers = copy.readShort();
        buf4355.writeShort(lineNumbers);
        for (int i = 0; i < lineNumbers; i++) {
            // 读取文本长度
            byte lineLength = copy.readByte();
            buf4355.writeByte(lineLength);
            buf4355.writeBytes(copy.readBytes(lineLength));
            byte ipLength = copy.readByte();
            copy.readBytes(ipLength);
            String ip = pluginConfig.getIp();
            buf4355.writeByte(ip.getBytes().length);
            buf4355.writeBytes(ip.getBytes());
        }
        // 读取buf剩余内容
        buf4355.writeBytes(copy.readBytes(copy.readableBytes()));
        copy = HexUtil.getFinalPacket(buf4355);
        return copy;
    }
    
    private ByteBuf dealLoginLine(ByteBuf copy) {
        ByteBuf buf3357 = Unpooled.buffer();
        copy.readBytes(10);
        buf3357.writeShort(copy.readShort());
        buf3357.writeInt(copy.readInt());
        buf3357.writeShort(copy.readShort());
        byte length = copy.readByte();
        copy.readBytes(length);
        buf3357.writeByte(pluginConfig.getIp().length());
        buf3357.writeBytes(pluginConfig.getIp().getBytes());
        buf3357.writeBytes(copy.readBytes(copy.readableBytes()));
        copy = HexUtil.getFinalPacket(buf3357);
        return copy;
    }
    
    private ByteBuf dealChoseLine(ByteBuf copy) {
        ByteBuf bufF0DF = Unpooled.buffer();
        copy.readBytes(10);
        bufF0DF.writeShort(copy.readShort());
        short lineNumber = copy.readShort();
        bufF0DF.writeShort(lineNumber);
        for (int i = 0; i < lineNumber; i++) {
            byte ipLength = copy.readByte();
            copy.readBytes(ipLength);
            bufF0DF.writeByte(pluginConfig.getIp().getBytes().length);
            bufF0DF.writeBytes(pluginConfig.getIp().getBytes());
            byte lineLength = copy.readByte();
            bufF0DF.writeByte(lineLength);
            bufF0DF.writeBytes(copy.readBytes(lineLength));
            bufF0DF.writeShort(copy.readShort());
        }
        copy = HexUtil.getFinalPacket(bufF0DF);
        return copy;
    }
    
    private ByteBuf dealChangeLine(ByteBuf copy) {
        ByteBuf buf20D5 = Unpooled.buffer();
        copy.readBytes(10);
        buf20D5.writeShort(copy.readShort());
        buf20D5.writeShort(copy.readShort());
        byte length = copy.readByte();
        String string = copy.readCharSequence(length, StandardCharsets.US_ASCII).toString();
        string = string.replace(gameConfig.getIp(), pluginConfig.getIp());
        buf20D5.writeByte(string.getBytes().length);
        buf20D5.writeBytes(string.getBytes());
        log.info("buf20D5: {}", HexUtil.byteBufToHex(buf20D5));
        copy = HexUtil.getFinalPacket(buf20D5);
        return copy;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("服务端连接发生异常", cause);
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("服务端连接断开");
        // 如果服务端断开连接，也关闭与客户端的连接
        if (clientChannel != null) {
            clientChannel.close();
        }
        ctx.close();
    }
}